//
//  Console.m
//  BehindTheMask
//
//  Created by Yosuke Suzuki on 08/03/11.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "Console.h"

#define USE_WEBKIT_AS_CONSOLE_VIEW 0

#define kConsoleLoggedAtKey @"AT"
#define kConsoleMessageKey @"MESSAGE"

@interface Console(Local)

- (void)addLogToView:(NSDictionary *)log;
- (UIView *)createView;
- (NSString *)viewInfo:(UIView *)view;
- (NSString *)stringWithCGPoint:(CGPoint)p;
- (NSString *)stringWithCGSize:(CGSize)s;
- (NSString *)stringWithCGRect:(CGRect)r;
- (NSString *)stringWithUIEdgeInsets:(UIEdgeInsets)i;

- (NSString *)correctViewInfo:(UIView *)view withIndent:(NSString *)indent into:(NSString *)result;

#if USE_WEBKIT_AS_CONSOLE_VIEW
- (NSString *)scriptForAppendLogText:(NSString *)logText;
#endif

@end

@implementation Console

@synthesize logs;
@synthesize hidden;
@synthesize unreadMessage;

static Console *sharedConsole;

+ (Console *)sharedConsole {
	if (!sharedConsole) sharedConsole = [[Console alloc] init];
	return sharedConsole;
}

+ (void)cleanUp {
	if (sharedConsole) [sharedConsole release];
}

- (id)init
{
	if (self = [super init]) {
		// Initialize your view controller.
		self.title = @"Console";
		self.toolbarItem.image = [UIImage imageNamed:@"Console.png"];
		self.logs = [NSMutableArray arrayWithCapacity:10];
	}
	return self;
}

- (void)log:(NSString *)message {
	NSLog(message);
	
	NSDictionary *log = [NSDictionary dictionaryWithObjectsAndKeys:
						 [NSDate date], kConsoleLoggedAtKey, 
						 message, kConsoleMessageKey, 
						 nil
					];
	
	[logs addObject:log];
	 
	if (viewCreated) {
		[self addLogToView:log];
	}
	
	if (self.hidden) {
		self.toolbarItem.badgeValue = [NSString stringWithFormat:@"%d", ++self.unreadMessage];
	}
}

- (NSString *)viewInfo:(UIView *)view {
	NSString *line = [NSString stringWithFormat:@"%@ (frame %@) (bound %@)", 
					  [view className], 
					  [self stringWithCGRect:view.frame], 
					  [self stringWithCGRect:view.bounds]];
	if ([view class] == [UIScrollView class]) {
		UIScrollView *sview = (UIScrollView *)view;
		line = [line stringByAppendingFormat:@" [contentSize: %@ contentOffset: %@ contentInset: %@]", 
				[self stringWithCGSize:sview.contentSize],
				[self stringWithCGPoint:sview.contentOffset],
				[self stringWithUIEdgeInsets:sview.contentInset]
		];
	}
	
	return line;
}

- (NSString *)stringWithCGPoint:(CGPoint)p {
	return [NSString stringWithFormat:@"%.0f, %.0f", p.x, p.y];
}

- (NSString *)stringWithCGSize:(CGSize)s {
	return [NSString stringWithFormat:@"%.0f, %.0f", s.width, s.height];
}

- (NSString *)stringWithCGRect:(CGRect)r {
	return [NSString stringWithFormat:@"%.0f, %.0f, %.0f, %.0f", 
			r.origin.x, r.origin.y, 
			r.origin.x + r.size.width, r.origin.y + r.size.height];
}

- (NSString *)stringWithUIEdgeInsets:(UIEdgeInsets)i {
	return [NSString stringWithFormat:@"%.0f, %.0f, %.0f, %.0f", 
			i.left, i.top, i.right, i.bottom];
}

- (NSString *)correctViewInfo:(UIView *)view withIndent:(NSString *)indent into:(NSString *)result {
	NSString *info = [indent stringByAppendingString:[self viewInfo:view]];
	
	result = [NSString stringWithFormat:@"%@\n%@", result, info];
	
	indent = [NSString stringWithFormat:@"  %@", indent];
	for (UIView *sub in [view subviews]) {
		result = [self correctViewInfo:sub withIndent:indent into:result];
	}
	
	return result;
}

- (void)dumpViewHierarchy:(UIView *)view {
	UIView *root = view.window ? view.window : view;
	NSString *desc = [NSString stringWithFormat:@"view hierarchy of %@", view];
	[self log: [self correctViewInfo:root withIndent:@"" into:desc]];
}

static NSUInteger logCounter = 0;
- (void)addLogToView:(NSDictionary *)log {
	NSString *logText = [NSString stringWithFormat:@"[%@ %d] %@", 
							[log objectForKey:kConsoleLoggedAtKey], 
							++logCounter, 
							[log objectForKey:kConsoleMessageKey]];
	
#if USE_WEBKIT_AS_CONSOLE_VIEW
	UIWebView *logView = (UIWebView *) self.view;
	NSString *script = [self scriptForAppendLogText:logText];
	
	NSLog(script);
	NSString *result = [logView stringByEvaluatingJavaScriptFromString:script];
	NSLog(result);
#else
	UITextView *logView = (UITextView *) self.view;
	logView.text = [NSString stringWithFormat:@"%@%@\n", logView.text, logText];
#endif
}

#if USE_WEBKIT_AS_CONSOLE_VIEW
- (NSString *)scriptForAppendLogText:(NSString *)logText {
	return [NSString stringWithFormat:@"document.writeln('<li>%@</li>');", logText];
}
#endif

- (UIView *)createView {
#if USE_WEBKIT_AS_CONSOLE_VIEW
	UIWebView *view = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
	[view loadHTMLString:@"<h1>Console</h1>" baseURL:nil];
#else
	UITextView *view = [[UITextView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
	view.editable = NO;
	view.font = [UIFont systemFontOfSize:10];
#endif
	
	view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
	
	if ([self.logs count] > 0) {
		for (NSDictionary *log in logs) {
			[self addLogToView:log];
		}
	}
	
	
	return [view autorelease];
}

- (void)loadView
{
	viewCreated = YES;
	
	// Create a custom view hierarchy.
	UIView *view = [self createView];
	self.view = view;
	
	[self log:@"consoleView loaded."];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
	// Return YES for supported orientations.
	return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)viewDidAppear:(BOOL)animated {
	self.hidden = NO;
	self.unreadMessage = 0;
	self.toolbarItem.badgeValue = nil;
}

- (void)viewWillDisappear:(BOOL)animated {
	self.hidden = YES;
}


@end
